local Config = require("Config")
local Msg = require("core.Msg")
local Lang = require("common.Lang")
local Util = require("common.Util")
local FamilyManager = require("family.FamilyManager")
local FamilyDefine = require("family.FamilyDefine")

local RoleDBLogic = require("role.RoleDBLogic")
local Human = require("core.Human")
local FamilyExcel = require("excel.Family")
local BuildingExcel = FamilyExcel.building
local OfficialExcel = FamilyExcel.official
local CreateExcel = FamilyExcel.create
local BannerExcel = FamilyExcel.banner

local RoleDefine = require("role.RoleDefine")
local Log = require("common.Log")
local LogDefine = require("common.LogDefine")
local GmCommon = require("chat.GmCommon")
local HtmlUtil = require("common.HtmlUtil")
local InnerDataManagerFW = require("innerdata.InnerDataManagerFW")
local InnerDataDefine = require("innerdata.Define")
local ItemDefine = require("bag.ItemDefine")

local Broadcast = require("broadcast.Broadcast")
local RoleFFI = require("role.RoleFFI")
local Grid =require("bag.Grid")
local MailLogicFW =require("mail.MailLogicFW")
local RankHandler = require("rank.HandlerW")
local CopyDefine = require("copy.Define")
local CopyW = require("copy.CopyW")
local CopyCommon = require("copy.CopyCommon")
local Timer = require("core.Timer")
local Map = require("core.Map")
local FamilyWarReward = require("excel.FamilyWar").WarReward[1]
local FamilyWarTequan = require("excel.FamilyWar").WarTequan
local MiddleFamilySign = require("middle.MiddleFamilySign")
local Config = require("Config")

local table = _G.table
local os = _G.os
local math = _G.math

fields = {
    account=1,
    familyContribution=1,
    familyUuid=1,
    head=1,
    lastLoginTime=1,
    lv=1,
    name=1,
    sex=1,
    zhandouli=1,
}

nSend2Ldata = nSend2Ldata or {}

local function getApplyed(family, human)
    if FamilyManager.isApplyed(family, human._id) then
        return 1
    end
    for i = 0, human.db.familyApplyListLen -1 do
        local familyUuid = RoleFFI.ffi_string(human.db.familyApplyList[i].uuid)
        if familyUuid == family._id and Util.isSameDay(human.db.familyApplyList[i].applyTime) then
            return 1
        end
    end
    return 0
end

function getAllyName(familyUuid)
    if not familyUuid then
        return ""
    end
    local ally = FamilyManager.getAlly(familyUuid)
    if not ally then
        return ""
    end
    return ally.familyName
end

function getAllyUuid(familyUuid)
    if not familyUuid then
        return ""
    end
    local ally = FamilyManager.getAlly(familyUuid)
    if not ally then
        return ""
    end
    return ally._id
end

--封装simple军团结构体
local function wrapperSimpleFamily(msgFamily, family, human, leader)
    msgFamily.familyUuid = family._id
    msgFamily.familyName = family.familyName
    msgFamily.familyBanner = family.familyBanner
    msgFamily.familyLv = family.familyLv
    msgFamily.leaderUuid = leader.uuid
    msgFamily.leaderName = leader.name
    msgFamily.memberCnt = #family.memberList
    msgFamily.memberMaxCnt = getMemberMaxCnt(family.familyLv)
    msgFamily.zhandouli = FamilyManager.getZhandouli(family)
    msgFamily.hasApply = getApplyed(family, human)
    msgFamily.allyUuid = getAllyUuid(family._id)
    msgFamily.familyWarRank = 0
    msgFamily.createTime = family.createTime
end

--封装军团结构体
local function wrapperFamily(msgFamily, family)
    local leader = FamilyManager.getLeader(family)
    msgFamily.familyUuid = family._id
    msgFamily.familyName = family.familyName
    msgFamily.familyBanner = family.familyBanner
    msgFamily.leaderUuid = leader.uuid
    msgFamily.leaderName = leader.name
    msgFamily.memberCnt = #family.memberList
    msgFamily.memberMaxCnt = getMemberMaxCnt(family.familyLv)
    msgFamily.sign = family.sign
    msgFamily.familyLv = family.familyLv
    msgFamily.familyMaxLv = #BuildingExcel
    msgFamily.createTime = family.createTime
    msgFamily.familyMoney = family.familyMoney
    msgFamily.familyExp = family.familyExp or 0
    msgFamily.familyExpMax = BuildingExcel[family.familyLv].needExp
    msgFamily.zhandouli = FamilyManager.getZhandouli(family)
    msgFamily.activityRate = family.activityRate or 0
    msgFamily.allyName = getAllyName(family._id)
    msgFamily.familyWarRank = 0                     --FamilyWarDB.getFamilyWarRank(family._id)
    msgFamily.familyMonsterLv = 0                   --FamilyMonsterLogic.getFamilyMonsterLv(family) or 0
    msgFamily.recruitSign = family.recruitSign or Lang.FAMILY_RECRUIT_SING
    msgFamily.banneritemdata[0] = 0
    for k, v in pairs(family.FamilyBannerItemData) do
        msgFamily.banneritemdata[0] = msgFamily.banneritemdata[0] + 1
        local itemData = msgFamily.banneritemdata[msgFamily.banneritemdata[0]]
        itemData.itemid = k
        itemData.itemnum = v
    end
end

--封装军团成员结构体
local function wrapperMember(msgMember, member)
    msgMember.uuid = member.uuid or member._id
    msgMember.name = member.name
    msgMember.head = member.head
    msgMember.lv = member.lv
    msgMember.sex = member.sex
    msgMember.official = member.official or 0
    msgMember.zhandouli = member.zhandouli or 0
    msgMember.familyContribution = member.familyContribution
    msgMember.familyContributionSum = 0
    if member.familyContributionSum then
        msgMember.familyContributionSum = member.familyContributionSum
    end
    msgMember.lastLoginTime = member.lastLoginTime
    local online = 0
    local target = Human.onlineUuid[msgMember.uuid]
    if target and target.fd then
        online = 1
        msgMember.zhandouli = target.db.zhandouli
    end
    msgMember.online = online
    
    msgMember.isFamilyWar = member.fwar and 1 or 0
    
    msgMember.blue = member.blue or "000"
end


--封装军团仓库记录结构体
local function wrapperFamilyStoreRecord(msgRecord, record)
    msgRecord.time = record.time
    msgRecord.content = HtmlUtil.fontName(record.name, record.uuid) ..FamilyDefine.FAMILY_STORE_RECORD_TIP[record.type]..HtmlUtil.fontItem(record.grid)
    msgRecord.type	= record.type
    return msgRecord.content
end

--封装军团旗帜结构体
--local function wrapperBannerConf(msgBanner, conf, lv)
--    msgBanner.lv = lv
--    msgBanner.desc = conf.desc
--    msgBanner.attrs[0] = 0
--    for k, v in pairs(conf.attrs) do
--        msgBanner.attrs[0] = msgBanner.attrs[0] + 1
--        local attr = msgBanner.attrs[msgBanner.attrs[0]]
--        attr.key = k
--        attr.value = v
--    end
--end

--军团成员更新
function memberUpdate(family, member)
    local msgRet = Msg.gc.GC_FAMILY_MEMBER_UPDATE
    local fds = FamilyManager.getOnlineFds(family)
    wrapperMember(msgRet.member, member)
    Msg.sendMulti(msgRet, fds)
end

--军团信息更新
function sendFamilyUpdate(family)
    local msgRet = Msg.gc.GC_FAMILY_QUERY
    msgRet.familyUuid = family._id
    wrapperFamily(msgRet.family, family)
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)
end

-- send contribution
function sendContribution(human, family)
    local msgRet = Msg.gc.GC_FAMILY_CONTRIBUTE
    msgRet.uuid = human._id
    msgRet.familyContribution = human.db.familyContribution
    msgRet.familyAlgContributionRmb = human.db.familyAlgContributionRmb
    msgRet.familyContributionSum = 0
    local humanMember = FamilyManager.getMember(family, human._id)
    if humanMember and humanMember.familyContributionSum then
        msgRet.familyContributionSum = humanMember.familyContributionSum
    end
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)
end

--军团成员最大值
function getMemberMaxCnt(familyLv)
    return FamilyManager.getMemberMaxCnt(familyLv)
end

--检查军团等级提升
function checkLevelUp(family)

    if family.familyLv == #BuildingExcel or not family.familyExp or not family.familyMoney then
        return
    end

    local levelUp
    --while family.familyExp > 0 and family.familyMoney > 0 do
    if family.familyExp > 0 and family.familyMoney > 0 then 
        local needExp = BuildingExcel[family.familyLv].needExp
        local needMoney = BuildingExcel[family.familyLv].needMoney
        if needExp <= family.familyExp and needMoney <= family.familyMoney then
            family.familyExp = family.familyExp - needExp
            family.familyMoney = family.familyMoney - needMoney
            family.familyLv = family.familyLv + 1
            levelUp = true
            --break
            --if family.familyLv == #BuildingExcel then
            --    family.familyExp = 0
            --    break
            --end
        end
    end
    return levelUp
end

--军团增加经验
function addFamilyExp(family, addExp, send, human)
    if not family.familyExp then
        family.familyExp = 0
    end
    local preFamilyExp = family.familyExp
    --family.familyExp = family.familyExp + addExp
    family.familyExp = math.min(family.familyExp + addExp, BuildingExcel[family.familyLv].needExp)
    --local up = checkLevelUp(family)
    --if up then
        ----family.dailyFamilyExp = nil
        --FamilyManager.update(family)
        --sendFamilyUpdate(family)

        --local msgRet = Msg.gc.GC_FAMILY_UP
        --msgRet.familyLv = family.familyLv
        --local fds = FamilyManager.getOnlineFds(family)
        --Msg.sendMulti(msgRet, fds)

        ----send member attr change
        --local nSend2Ldata = {
        --    type = 8,
        --    familyUuid = family._id,
        --    memberList = family.memberList,
        --}
        --InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
    --else
        if send and preFamilyExp ~= family.familyExp then
            sendFamilyUpdate(family)
        end

        if human and addExp > 0 then
            local msgRet = Msg.gc.GC_FAMILY_ADD_EXP
            msgRet.exp = addExp
            Msg.send(msgRet, human.fd)
        end
    --end
end

function addBannerItemNum(human, family, oItemData)
    for k, v in pairs(oItemData) do
        local nBannerItemData = family.FamilyBannerItemData
        if nBannerItemData then
            nBannerItemData[v[1]] = (nBannerItemData[v[1]] or 0) + v[2]
        end
    end
    updateFamilyBanner(family)
end

function updateFamilyBanner(family)
    FamilyManager.update(family)
    sendFamilyUpdate(family)
end

--军团增加基金
function updateFamilyMoney(family, value, send)
    local money = family.familyMoney + value
    if money < 0  or value == 0 then
        assert()
    end
    family.familyMoney = money
    FamilyManager.update(family)
    if send then
        sendFamilyUpdate(family)
    end
end

--设置军团贡献	内部使用，正常模块使用　updateFamilyContribution
function setFamilyContribution(human, val)
    local family = FamilyManager.findByUuid(human.familyUuid)
    if family then
        FamilyManager.setContribution(human, val)
    end
end

-- 杀怪经验值
function getKillMonsterExpAddValue(human)
    local addValue = 0
    local family = FamilyManager.findByUuid(human.familyUuid)
    if family then
        local conf = BuildingExcel[family.familyLv]
        if conf then
            for k, v in pairs(conf.attrs) do
                if k == RoleDefine.KILL_MONSTER_EXP_ADD then
                    addValue = addValue + v
                end
            end
        end
    end
    return addValue
end

-- 杀怪经验比率
function getKillMonsterExpAddRate(human)
    local addRate = 0
    local family = FamilyManager.findByUuid(human.familyUuid)
    if family then
        --banner
        local conf = BuildingExcel[family.familyLv]
        if conf then
            for k, v in pairs(conf.attrs) do
                if k == RoleDefine.KILL_MONSTER_EXP_ADD_RATE then
                    addRate = addRate + v
                end
            end
        end

        --print("addRate before:", addRate)
        addRate = addRate + 0           --FamilyWarDB.getFamilyExpAdd(human.db.familyUuid)
        --print("addRate after:", addRate)
    end
    return addRate
end

function createResult(human, createType, success, familyUuid)
    --local msg = Msg.wl.WL_FAMILY_CREATE_FAILED
    --msg.createType = createType
    --msg.result = success and 0 or 1
    --Msg.send2logic(msg, human.fd)

    local nSend2Ldata = {
        type = 1,
        result = success and 0 or 1 ,
        createType = createType,
        familyUuid = familyUuid or "",
    }
    InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
end

-- 军团创建
function create(human, createType, familyName)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    if FamilyManager.findByFamilyName(familyName) then
        msgErr.msg = Lang.FAMILY_CREATE_SAME_NAME
        Msg.send(msgErr, human.fd)
        onSendJoinFamily(human, nil, 1, false, createType)
        return
    end

    msgErr.msg = Lang.FAMILY_CREATE_OK
    Msg.send(msgErr, human.fd)
    local familyLv
    if createType == 0 then
        familyLv = 1
    else
        familyLv = 2
    end
    local result = FamilyManager.create(human, familyName, familyLv)
    if result then
        local family = FamilyManager.findByUuid(human.familyUuid)
        if family then
            local msgRet = Msg.gc.GC_FAMILY_CREATE
            msgRet.familyUuid = RoleFFI.ffi_string(human.familyUuid)
            Msg.send(msgRet, human.fd)
            onSendJoinFamily(human, family, 1, true, createType)
            Broadcast.sendBroadcast2World(Lang.UP + Lang.GROSSIP, string.format(Lang.FAMILY_CREATE_OK_BROADCAST, HtmlUtil.fontName(human.name, human._id), familyName))
            Log.write(Log.LOGID_OSS_FAMILY_INFO, family._id, family.familyName, human.name, FamilyManager.getLeader(family).name or "", family.familyLv, family.familyMoney, family.familyBanner)
            return
        end
    end
    onSendJoinFamily(human, nil, 1, false, createType)
end

--军团查询
function CG_FAMILY_QUERY(human, familyUuid)
    local msgRet = Msg.gc.GC_FAMILY_QUERY
    msgRet.familyUuid = familyUuid
    local family = FamilyManager.findByUuid(familyUuid)
    if not family then
        return
    end
    wrapperFamily(msgRet.family, family)
    Msg.send(msgRet, human.fd)
end

-- cmp
local function familycmp(a, b)
    if a.familyLv ~= b.familyLv then
        return a.familyLv > b.familyLv
    end
    if #a.memberList ~= #b.memberList then
        return #a.memberList > #b.memberList
    end
end

-- list
familySimpleList = familySimpleList or {}
local function getFamilySimpleList()

    --clear
    for index in ipairs(familySimpleList) do
        familySimpleList[index] = nil
    end

    -- make list
    for _, family in pairs(FamilyManager.uuid2Family) do
        familySimpleList[#familySimpleList+1] = family
    end

    table.sort(familySimpleList, familycmp)
    return familySimpleList
end

--军团列表
function CG_FAMILY_LIST(human)
    local msgRet = Msg.gc.GC_FAMILY_LIST
    msgRet.familys[0] = 0
    local l = getFamilySimpleList()
    for _, family in ipairs(l) do
        if msgRet.familys[0] >= #msgRet.familys then
            break
        end
        local leader = FamilyManager.getLeader(family)
        if leader then
            msgRet.familys[0] = msgRet.familys[0] + 1
            wrapperSimpleFamily(msgRet.familys[msgRet.familys[0]], family, human, leader)
        end
    end
    Msg.send(msgRet, human.fd)
end

function CG_FAMILY_LVUP(human)
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return
    end

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    if family.familyMoney < BuildingExcel[family.familyLv].needMoney then
        msgErr.msg = Lang.FAMILY_FAMILY_MONEY_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)) then
        msgErr.msg = Lang.FAMILY_OFFICIAL_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    local up = checkLevelUp(family)
    if up then
        --family.dailyFamilyExp = nil
        FamilyManager.update(family)
        sendFamilyUpdate(family)

        local msgRet = Msg.gc.GC_FAMILY_UP
        msgRet.result = 0
        msgRet.familyLv = family.familyLv
        msgRet.familyLvUpNeedMoney = BuildingExcel[family.familyLv].needMoney 
        local fds = FamilyManager.getOnlineFds(family)
        Msg.sendMulti(msgRet, fds)

        --send member attr change
        local nSend2Ldata = {
            type = 8,
            familyUuid = family._id,
            memberList = family.memberList,
            familyLv = family.familyLv
        }
        InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
        local fds = FamilyManager.getOnlineFds(family)
        Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_LVUP_SUCESS_BROADCAST, HtmlUtil.fontName(human.name, human._id), family.familyLv))
    else
        msgErr.msg = Lang.FAMILY_LVUP_NOTEXP
        Msg.send(msgErr, human.fd)
        return
    end
end

--申请加入军团
function CG_FAMILY_APPLY(human, familyUuid)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if family then
        msgErr.msg = Lang.FAMILY_APPLY_MUST_EXIT_FAMIL
        Msg.send(msgErr, human.fd)
        return
    end

    local nowFamily = FamilyManager.findByUuid(familyUuid)
    if not nowFamily then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if (os.time() - human.db.familyExitTime) < FamilyDefine.FAMILY_EXITTIME then
        msgErr.msg = Lang.FAMILY_CREATE_NEED_NEXT_DAY
        Msg.send(msgErr, human.fd)
        return
    end

    if human.db.gm == 100 then
        msgErr.msg = Lang.FAMILY_CREATE_GUIDE_GM
        Msg.send(msgErr, human.fd)
        return
    end

    if human.db.lv < CreateExcel[1].createMinLv then
        msgErr.msg = string.format(Lang.FAMILY_JOIN_LV_NOT_ENOUGH, CreateExcel[1].createMinLv)
        Msg.send(msgErr, human.fd)
        return
    end

    if #nowFamily.memberList >= getMemberMaxCnt(nowFamily.familyLv) then
        msgErr.msg = Lang.FAMILY_FAMILY_FULL
        Msg.send(msgErr, human.fd)
        return
    end

    --判断是否在目标军团的邀请列表中
    if FamilyManager.isInvited(nowFamily, human.name) then
        CG_FAMILY_INVITE_AGREE(human, nowFamily._id)
        return
    end

    if FamilyManager.getApplyListLen(nowFamily) >= FamilyDefine.APPLY_LIST_MAX_CNT then
        msgErr.msg = Lang.FAMILY_APPLY_LIST_FULL
        Msg.send(msgErr, human.fd)
        return
    end

    local applyCode = getApplyed(nowFamily, human)
    if applyCode == 1 then
        msgErr.msg = Lang.FAMILY_APPLY_TWICE
        Msg.send(msgErr, human.fd)
        return
    end

    if nowFamily.familyApplyState == 1 then
        if FamilyManager.addMember(nowFamily, human.db, FamilyDefine.OFFICIAL_NORMAL, human) then
            local msgRet = Msg.gc.GC_FAMILY_MEMBER_ADD
            msgRet.familyUuid = nowFamily._id
            msgRet.member[0] = 0

            local m = FamilyManager.getMember(nowFamily, human._id)
            msgRet.tip = string.format(Lang.FAMILY_MEMBER_ADD, HtmlUtil.fontName(human.name, human._id))
            msgRet.member[0] = 1
            wrapperMember(msgRet.member[msgRet.member[0]], m)

            local fds = FamilyManager.getOnlineFds(nowFamily)
            Msg.sendMulti(msgRet, fds)

            msgErr.msg = Lang.FAMILY_JOIN_OK
            Msg.send(msgErr, human.fd)
            onSendJoinFamily(human, nowFamily, 0)
        end
    else
        FamilyManager.addApply(nowFamily, human)
        msgErr.msg = Lang.FAMILY_APPLY_OK
        Msg.send(msgErr, human.fd)

        local msgRet = Msg.gc.GC_FAMILY_APPLY
        msgRet.familyUuid = familyUuid
        Msg.send(msgRet, human.fd)

        local fds = FamilyManager.getAuthFds(nowFamily, FamilyManager.auth1)

        if fds[0] ~= 0 then
            msgErr.type = Lang.DOWN
            msgErr.msg = Lang.FAMILY_SOME_ONE_APPLY
            Msg.sendMulti(msgErr, fds)
        end
    end
end

function onSendJoinFamily(human, family, iscreate, createResult, createType)
    local nSend2Ldata = {
        type = 20,
        iscreate = iscreate,
        result = createResult and 0 or 1 ,
        createType = createType,
        familyUuid = family and family._id or "",
        familyName = family and family.familyName or "",
    }
    InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)

end

function onSendExitFamily(human)
    local nSend2Ldata = {
        type = 21,
    }
    InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
end

-- 取消申请加入军团
function CG_FAMILY_APPLY_CANCEL(human, familyUuid)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if family then
        msgErr.msg = Lang.FAMILY_APPLY_MUST_EXIT_FAMIL
        Msg.send(msgErr, human.fd)
        return
    end

    local tFamily = FamilyManager.findByUuid(familyUuid)
    if not FamilyManager.isApplyed(tFamily, human._id) then
        msgErr.msg = Lang.FAMILY_NOT_IN_APPLY_LIST
        Msg.send(msgErr, human.fd)
        return
    end

    FamilyManager.delApply(tFamily, human._id, string.format(Lang.FAMILY_APPLY_CANCEL_OK))
end


--查询申请列表
function CG_FAMILY_APPLY_LIST(human)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local msgRet = Msg.gc.GC_FAMILY_APPLY_LIST
    msgRet.applys[0] = 0
    local family = FamilyManager.findByUuid(human.familyUuid)
    msgRet.applystate = family.familyApplyState or 0
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end
    if family.applyList then
        for k, v in pairs(family.applyList) do
            if FamilyManager.isApplyed(family, v.uuid) then
                msgRet.applys[0] = msgRet.applys[0] + 1
                wrapperMember(msgRet.applys[msgRet.applys[0]], v)
            end
        end
    end
    Msg.send(msgRet, human.fd)
end

--同意某人申请加入军团
function CG_FAMILY_APPLY_AGREE(human, targetUuid, ntype)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end
  
    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end
    local result = true
    local msg = ""
    local nSucessList = {}
    if ntype == 0 then
        local targetDB = RoleDBLogic.getDbByUuid(targetUuid)
        if not targetDB then
          return
        end
        result, msg = applymenber(targetUuid, family)
        if result then
            table.insert(nSucessList, targetUuid)
            Log.write(Log.LOGID_OSS_FAMILY_ENTER_AND_EXIT, type(targetDB._id) == "string" and targetDB._id or RoleFFI.ffi_string(targetDB._id), type(targetDB.account) == "string" and targetDB.account or RoleFFI.ffi_string(targetDB.account), type(targetDB.name) == "string" and targetDB.name or RoleFFI.ffi_string(targetDB.name), family._id, family.familyName, family.familyLv, LogDefine.FAMILY_ENTER_ACTION.ENTER)
        end
    elseif ntype == 1 then
        if family.applyList then
            for k in pairs(family.applyList) do
                result, msg = applymenber(k, family)
                if result then
                    table.insert(nSucessList, k)
                    local targetDB = RoleDBLogic.getDbByUuid(k)
                    Log.write(Log.LOGID_OSS_FAMILY_ENTER_AND_EXIT, k, "", "", family._id, family.familyName, family.familyLv, LogDefine.FAMILY_ENTER_ACTION.ENTER)
                end
            end
        end
    end

    CG_FAMILY_APPLY_LIST(human)

    if #nSucessList > 0 then
        local msgRet = Msg.gc.GC_FAMILY_MEMBER_ADD
        msgRet.familyUuid = family._id
        msgRet.member[0] = 0
        msgRet.tip = ""
        for k, v in ipairs(nSucessList) do
            local target = Human.onlineUuid[v]
            if target and target.fd then
                target.familyUuid = human.familyUuid
                target.familyName = human.familyName
                msgErr.msg = Lang.FAMILY_JOIN_OK
                Msg.send(msgErr, target.fd)
                onSendJoinFamily(target, family, 0)
            end

            local m = FamilyManager.getMember(family, v)
            msgRet.tip = string.format(Lang.FAMILY_MEMBER_ADD, HtmlUtil.fontName(m.name, m.uuid))
            msgRet.member[0] = k
            wrapperMember(msgRet.member[msgRet.member[0]], m)

            --if target then
            --    RoleUIControl.sendLine1FnIcon(target)
            --end
        end

        --save familyid
        --targetDB.familyUuid = family._id
        --if not target then
        --    RoleDBLogic.saveRoleSset(targetDB)
        --end

        -- notify family add member
        local fds = FamilyManager.getOnlineFds(family)

        Msg.sendMulti(msgRet, fds)
        
    end

    if ntype == 0 then
        msgErr.msg = msg
        Msg.send(msgErr, human.fd)
    end
end

function applymenber(targetUuid, family)
    local targetDB = RoleDBLogic.getDb(targetUuid, fields)

    if not targetDB then
        --msgErr.msg = Lang.FAMILY_TARGET_UUID_INVALID
        --Msg.send(msgErr, human.fd)
        return false, Lang.FAMILY_TARGET_UUID_INVALID
    end

    if RoleFFI.ffi_string(targetDB.familyUuid) ~= "" then
        --msgErr.msg = Lang.FAMILY_TARGET_HAS_FAMILY
        --Msg.send(msgErr, human.fd)
        if FamilyManager.isApplyed(family, targetUuid) then
            FamilyManager.delApply(family, targetUuid)
        end
        if RoleFFI.ffi_string(targetDB.familyUuid) == family._id then
            return false, Lang.FAMILY_TARGET_HAS_SAMEAGREE
        else
            return false, Lang.FAMILY_TARGET_HAS_FAMILY
        end
    end

    if not FamilyManager.isApplyed(family, targetUuid) then
        --msgErr.msg = Lang.FAMILY_NOT_IN_APPLY_LIST
        --Msg.send(msgErr, human.fd)
        return false, Lang.FAMILY_NOT_IN_APPLY_LIST
    end

    if #family.memberList >= getMemberMaxCnt(family.familyLv) then
        if FamilyManager.isApplyed(family, targetUuid) then
            FamilyManager.delApply(family, targetUuid)
        end
        --msgErr.msg = Lang.FAMILY_FAMILY_FULL
        --Msg.send(msgErr, human.fd)
        return false, Lang.FAMILY_FAMILY_FULL
    end

    if not FamilyManager.addMember(family, targetDB, FamilyDefine.OFFICIAL_NORMAL) then
        --msgErr.msg = Lang.FAMILY_ADD_MEMBER_FAIL
        --Msg.send(msgErr, human.fd)
        return false, Lang.FAMILY_ADD_MEMBER_FAIL
    end

    FamilyManager.delApplys(targetUuid)
    FamilyManager.delInvites(targetUuid)
    return true, ""
end

--拒绝某人申请加入军团
function CG_FAMILY_APPLY_REFUSE(human, type, targetUuid)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    if type == 0 then
        if not FamilyManager.isApplyed(family, targetUuid) then
            msgErr.msg = Lang.FAMILY_NOT_IN_APPLY_LIST
            Msg.send(msgErr, human.fd)
            return
        end
        FamilyManager.delApply(family, targetUuid, string.format(Lang.FAMILY_REFUSE_JOIN, family.familyName))
    elseif type == 1 then
        if not family.applyList then
            return false
        end
        for k, v in pairs(family.applyList) do
            FamilyManager.delApply(family, k)
        end
    end

    CG_FAMILY_APPLY_LIST(human)
end

--邀请加入军团
function CG_FAMILY_INVITE(human, targetname)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    local target = Human.onlineHuman[targetname]

    if not target then
        msgErr.msg = Lang.FAMILY_TARGET_NOT_ONLINE
        Msg.send(msgErr, human.fd)
        return
    end

    if target.db.familyReject == 1 then
        msgErr.msg = string.format(Lang.FAMILY_INVITE_REJECT, targetname)
        Msg.send(msgErr, human.fd)
        return
    end

    if target.db.gm == 100 then
        msgErr.msg = Lang.FAMILY_CREATE_GUIDE_GM
        Msg.send(msgErr, human.fd)
        return
    end

    local targetDB = target.db

    if string.len(RoleFFI.ffi_string(targetDB.familyUuid)) > 0 then
        msgErr.msg = Lang.FAMILY_TARGET_HAS_FAMILY
        Msg.send(msgErr, human.fd)
        return
    end

    if targetDB.lv < CreateExcel[1].createMinLv then
        msgErr.msg = string.format(Lang.FAMILY_TARGET_LV_NOT_ENOUGH, CreateExcel[1].createMinLv)
        Msg.send(msgErr, human.fd)
        return
    end

    if Util.getInterval(targetDB.familyExitTime) <= FamilyDefine.FAMILY_EXITTIME then
        msgErr.msg = Lang.FAMILY_TARGET_ENTER_NEED_NEXT_DAY
        Msg.send(msgErr, human.fd)
        return
    end

    if #family.memberList >= getMemberMaxCnt(family.familyLv) then
        msgErr.msg = Lang.FAMILY_FAMILY_FULL
        Msg.send(msgErr, human.fd)
        return
    end

    --if family.familyLv < 3 then
    --    msgErr.msg = Lang.FAMILY_INVITE_LV_INVALID
    --    Msg.send(msgErr, human.fd)
    --    return
    --end

    --check auth
    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or  FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    --判断目标是否在本军团的申请列表中
    if FamilyManager.isApplyed(family, target._id) then
        CG_FAMILY_APPLY_AGREE(human, target._id)
        return
    end

    if FamilyManager.getInviteListLen(family) >= FamilyDefine.INVITE_LIST_MAX_CNT then
        msgErr.msg = Lang.FAMILY_INVITE_LIST_FULL
        Msg.send(msgErr, human.fd)
        return
    end

    if FamilyManager.isInvited(family, targetname) then
        msgErr.msg = Lang.FAMILY_INVITE_TWICE
        Msg.send(msgErr, human.fd)
        return
    end

    FamilyManager.addInvite(family, targetname)

    msgErr.msg = Lang.FAMILY_INVITE_OK
    Msg.send(msgErr, human.fd)

    msgErr.msg = Lang.FAMILY_SOME_ONE_INVITE
    Msg.send(msgErr, target.fd)

    local msgRet = Msg.gc.GC_FAMILY_INVITE_LIST
    msgRet.invitorUuid = human._id
    msgRet.invitorName = human.name
    wrapperFamily(msgRet.family, family)
    Msg.send(msgRet, target.fd)

end

local function getIndex(len, outTable)
    local index = math.random(1, len)
    for _, value in ipairs(outTable) do
        if value == index then
            return getIndex(len, outTable)
        end
    end
    return index
end

--军团推荐列表
function CG_FAMILY_COMMEND_LIST(human)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    local member = FamilyManager.getMember(family, human._id)
    if member.official ~= FamilyDefine.OFFICIAL_LEADER and member.official ~= FamilyDefine.OFFICIAL_FU_LEADER then
        msgErr.msg = Lang.FAMILY_OFFICIAL_AUTHORITY_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    local onlineHuman = {}
    for _, objHuman in pairs(Human.onlineUuid) do
        local uuid = RoleFFI.ffi_string(objHuman.db.familyUuid)
        if string.len(uuid) == 0 and objHuman.db.lv >= CreateExcel[1].createMinLv
            and not FamilyManager.isInvited(family, objHuman.name) then
            onlineHuman[#onlineHuman + 1] = objHuman
        end
    end

    local msgRet = Msg.gc.GC_FAMILY_COMMEND_LIST
    msgRet.members[0] = 0
    local outTable = {}
    local len = math.min(10, #onlineHuman)
    for i=1, len do
        local index = getIndex(#onlineHuman, outTable)
        outTable[#outTable + 1] = index
        msgRet.members[0] = msgRet.members[0] + 1
        wrapperMember(msgRet.members[msgRet.members[0]], onlineHuman[index].db)
    end
    Msg.send(msgRet, human.fd)
end

--同意某人军团邀请
function CG_FAMILY_INVITE_AGREE(human, familyUuid)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local selfFamily = FamilyManager.findByUuid(human.familyUuid)
    if selfFamily then
        msgErr.msg = Lang.FAMILY_HAS_FAMILY
        Msg.send(msgErr, human.fd)
        return
    end

    local family = FamilyManager.findByUuid(familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if not FamilyManager.isInvited(family, human.name) then
        msgErr.msg = Lang.FAMILY_NOT_IN_INVITE_LIST
        Msg.send(msgErr, human.fd)
        return
    end

    if #family.memberList >= getMemberMaxCnt(family.familyLv) then
        msgErr.msg = Lang.FAMILY_FAMILY_FULL
        Msg.send(msgErr, human.fd)
        FamilyManager.delInvite(family, human.name)
        return
    end

    FamilyManager.delApplys(human._id)
    FamilyManager.delInvites(human.name)
    FamilyManager.addMember(family, human.db, FamilyDefine.OFFICIAL_NORMAL, human)
    onSendJoinFamily(human, family, 0)

    --CG_FAMILY_QUERY(human, human.familyUuid)

    msgErr.msg = Lang.FAMILY_JOIN_OK
    Msg.send(msgErr, human.fd)

    -- notify family add member
    local m = FamilyManager.getMember(family, human._id)
    local msgRet = Msg.gc.GC_FAMILY_MEMBER_ADD
    msgRet.member[0] = 1
    msgRet.familyUuid = family._id
    msgRet.tip = string.format(Lang.FAMILY_MEMBER_ADD, HtmlUtil.fontName(m.name, m.uuid))
    wrapperMember(msgRet.member[msgRet.member[0]], m)
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)

    -- title change
    --local titleMsg = Msg.gc.GC_FAMILY_TITLE_CHANGE
    --titleMsg.objID = human.id
    --titleMsg.familyUuid = family._id
    --titleMsg.familyName = family.familyName
    --titleMsg.familyOfficial = FamilyDefine.OFFICIAL_NORMAL
    --titleMsg.allyName = getAllyName(family._id)
    --Obj.sendArea(titleMsg, human.scene_id, human.x, human.y)

    Log.write(Log.LOGID_OSS_FAMILY_ENTER_AND_EXIT, human._id, human.account, human.name, family._id, family.familyName, family.familyLv, LogDefine.FAMILY_ENTER_ACTION.ENTER)
end

--拒绝某人军团邀请
function CG_FAMILY_INVITE_REFUSE(human, familyUuid, invitorUuid)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local selfFamily = FamilyManager.findByUuid(human.familyUuid)
    if selfFamily then
        msgErr.msg = Lang.FAMILY_HAS_FAMILY
        Msg.send(msgErr, human.fd)
        FamilyManager.delInvites(human.name)
        return
    end

    local family = FamilyManager.findByUuid(familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    FamilyManager.delInvite(family, human.name)

    local target = Human.onlineUuid[invitorUuid]
    if target then
        msgErr.type = Lang.DOWN
        msgErr.msg = string.format(Lang.FAMILY_REFUSE_FAMILY_INVITE, human.name)
        Msg.send(msgErr, target.fd)
    end

end

--查询成员列表
function CG_FAMILY_MEMBER_LIST(human)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local msgRet = Msg.gc.GC_FAMILY_MEMBER_LIST
    msgRet.members[0] = 0

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    for _, member in ipairs(family.memberList) do
        if msgRet.members[0] >= #msgRet.members then
            break
        end
        msgRet.members[0] = msgRet.members[0]  + 1
        wrapperMember(msgRet.members[msgRet.members[0]], member)
    end
    Msg.send(msgRet, human.fd)
end

function kickallmember(family)
    local onlineUuid = Human.onlineUuid
    for _, member in ipairs(family.memberList) do
        local nHuman = onlineUuid[member.uuid]
        if nHuman then
            if nHuman.familyUuid == family._id then
                nHuman.db.familyUuid = ""
                nHuman.db.familyName = ""
                nHuman.familyUuid = ""
                nHuman.familyName = ""
                nHuman.familyWarResult = 0
                nHuman.db.familyExitTime = os.time()
                local fds = FamilyManager.getOnlineFds(family)

                FamilyManager.delMember(family, nHuman._id)
                if #family.memberList <= 0 then
                    FamilyManager.destory(family, nHuman._id)
                end
                RankHandler.familyChange(nHuman._id)

                -- notify family del member
                local msgRet = Msg.gc.GC_FAMILY_MEMBER_DEL
                msgRet.targetUuid = nHuman._id
                msgRet.tip = string.format(Lang.FAMILY_MEMBER_DEL, HtmlUtil.fontName(nHuman.name, nHuman._id))
                Msg.sendMulti(msgRet, fds)

                local nSend2Ldata = {
                    type = 11,
                    familyUuid = family.familyUuid,
                    memberList = family.memberList,
                }
                InnerDataManagerFW.Send2LInnerData(nHuman, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)

            end
        end
    end
    return 0 
end

--退出军团
function CG_FAMILY_EXIT(human)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    local leader = FamilyManager.getLeader(family)
    if leader.uuid == human._id and #family.memberList > 1 then
        msgErr.msg = string.format(Lang.FAMILY_LEADER_EXIT_FAMILY, family.officialName[leader.official])
        Msg.send(msgErr, human.fd)
        return
    end

    if inAllyTime(family.allySrcTime) then
        msgErr.msg = Lang.FAMILY_NO_CHANGE_LEADER_IN_ALLY
        Msg.send(msgErr, human.fd)
        return
    end

    human.db.familyUuid = ""
    human.db.familyName = ""
    human.db.familyWarResult = 0
    human.familyUuid = ""
    human.familyName = ""

    
    human.db.familyExitTime = os.time()
    local fds = FamilyManager.getOnlineFds(family)

    if #family.memberList > 1 then
        FamilyManager.delMember(family, human._id)
        msgErr.msg = Lang.FAMILY_EXIT_FAMILY_OK
        Msg.send(msgErr, human.fd)
    else
        FamilyManager.delMember(family, human._id)
        FamilyManager.destory(family, human._id)
    end
    RankHandler.familyChange(human._id)

    -- notify family del member
    local msgRet = Msg.gc.GC_FAMILY_MEMBER_DEL
    msgRet.targetUuid = human._id
    msgRet.tip = string.format(Lang.FAMILY_MEMBER_DEL, HtmlUtil.fontName(human.name, human._id))
    Msg.sendMulti(msgRet, fds)

    local nSend2Ldata = {
        type = 11,
        familyUuid = family.familyUuid,
        memberList = family.memberList,
    }
    InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)

    -- title change
    --local titleMsg = Msg.gc.GC_FAMILY_TITLE_CHANGE
    --titleMsg.objID = human.id
    --titleMsg.familyUuid = ""
    --titleMsg.familyName = ""
    --titleMsg.familyOfficial = 0
    --titleMsg.allyName = ""
    --Obj.sendArea(titleMsg, human.scene_id, human.x, human.y)

    Log.write(Log.LOGID_OSS_FAMILY_ENTER_AND_EXIT, human._id, human.account, human.name, family._id, family.familyName, family.familyLv, LogDefine.FAMILY_ENTER_ACTION.EXIT)
end

--T人
function CG_FAMILY_KICK(human, targetUuid)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if family.extendStartTime then
        msgErr.msg = Lang.FAMILY_NOT_KICK
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, RoleFFI.ffi_string(human._id)) or  FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, RoleFFI.ffi_string(human._id))) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local targetDB = RoleDBLogic.getDb(targetUuid, fields)
    local targetMember = FamilyManager.getMember(family, targetUuid)
    if not targetDB or not targetMember then
        msgErr.msg = Lang.FAMILY_TARGET_UUID_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    if human._id == targetUuid then
        msgErr.msg = Lang.FAMILY_KICK_SELF
        Msg.send(msgErr, human.fd)
        return
    end

    local leader = FamilyManager.getLeader(family)
    if leader.uuid == targetUuid then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local target = Human.onlineUuid[targetUuid]
    if target then
        msgErr.msg = Lang.FAMILY_BE_KICK
        Msg.send(msgErr, target.fd)
    end

    targetDB._id = targetUuid
    targetDB.familyUuid = ""
    targetDB.familyExitTime = os.time()
    local target = Human.onlineUuid[targetUuid]
    if target then
        target.familyUuid = ""
        target.familyName = ""
        target.db.familyUuid = ""
        target.db.familyName = ""
        target.db.familyWarResult = 0
        onSendExitFamily(target, family)
    end
    if not target then
        RoleDBLogic.saveRoleSset(targetDB)
    end

    local fds = FamilyManager.getOnlineFds(family)
    FamilyManager.delMember(family, targetUuid)
    RankHandler.familyChange(targetUuid)

    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_KICK_OK, HtmlUtil.fontName(targetMember.name, targetMember.uuid)))

    -- notify family del member
    local msgRet = Msg.gc.GC_FAMILY_MEMBER_DEL
    msgRet.tip = ""
    msgRet.targetUuid = targetUuid
    Msg.sendMulti(msgRet, fds)

    Log.write(Log.LOGID_OSS_FAMILY_ENTER_AND_EXIT, type(targetDB._id) == "string" and targetDB._id or RoleFFI.ffi_string(targetDB._id), type(targetDB.account) == "string" and targetDB.account or RoleFFI.ffi_string(targetDB.account), type(targetDB.name) == "string" and targetDB.name or RoleFFI.ffi_string(targetDB.name), family._id, family.familyName, family.familyLv, LogDefine.FAMILY_ENTER_ACTION.EXIT)
end

--更换军团旗帜
--function CG_FAMILY_CHANGE_BANNER(human, banner)
--    local msgErr = Msg.gc.GC_BROADCAST
--    msgErr.type = Lang.MOUSE
--
--    local familyUuid = human.db.familyUuid
--    local family = FamilyManager.findByUuid(human.familyUuid)
--
--    local leader = FamilyManager.getLeader(family)
--    if human._id ~= leader.uuid then
--        msgErr.msg = Lang.FAMILY_NOT_LEADER
--        Msg.send(msgErr, human.fd)
--        return
--    end
--
--    local needFamilyMoney = CreateExcel[1].needFamilyMoney
--    if family.familyMoney < needFamilyMoney then
--        msgErr.msg = Lang.FAMILY_FAMILY_MONEY_NOT_ENOUGH
--        Msg.send(msgErr, human.fd)
--        return
--    end
--
--    family.familyBanner = banner
--    family.familyMoney = family.familyMoney - needFamilyMoney
--    FamilyManager.update(family)
--
--    local msgRet = Msg.gc.GC_FAMILY_CHANGE_BANNER
--    msgRet.banner = banner
--    local fds = FamilyManager.getOnlineFds(family)
--    Msg.send(msgRet, fds)
--
--    msgRet = Msg.gc.GC_FAMILY_QUERY
--    msgRet.familyUuid = familyUuid
--    wrapperFamily(msgRet.family, family)
--    local fds = FamilyManager.getOnlineFds(family)
--    Msg.sendMulti(msgRet, fds)
--
--end

-- 军团官职名查询
function CG_FAMILY_OFFICIAL_NAME_QUERY(human)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    local msgRet = Msg.gc.GC_FAMILY_OFFICIAL_NAME_CHANGE
    msgRet.leader = family.officialName[FamilyDefine.OFFICIAL_LEADER]
    msgRet.fu_leader = family.officialName[FamilyDefine.OFFICIAL_FU_LEADER]
    msgRet.jingying = family.officialName[FamilyDefine.OFFICIAL_JINGYING]
    msgRet.normal = family.officialName[FamilyDefine.OFFICIAL_NORMAL]
    Msg.send(msgRet, human.fd)
end

--军团官职名改变
function CG_FAMILY_OFFICIAL_NAME_CHANGE(human, leader, fu_leader, zhanglao, jingying, normal)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    local leaderMember = FamilyManager.getLeader(family)

    if leaderMember.uuid ~= human._id then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    --filter
    if GmCommon.filter_name(leader) ~= leader then
        msgErr.msg = Lang.FAMILY_LEADER_WORD_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    if GmCommon.filter_name(fu_leader) ~= fu_leader then
        msgErr.msg = Lang.FAMILY_FU_LEADER_WORD_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    if GmCommon.filter_name(zhanglao) ~= zhanglao then
        msgErr.msg = Lang.FAMILY_ZHANGLAO_WORD_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    if GmCommon.filter_name(jingying) ~= jingying then
        msgErr.msg = Lang.FAMILY_JINGYING_WORD_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    if GmCommon.filter_name(normal) ~= normal then
        msgErr.msg = Lang.FAMILY_NORMAL_WORD_INVALID
        Msg.send(msgErr, human.fd)
        return
    end


    local officialLen = string.len(leader)
    if officialLen <= 0 or officialLen > FamilyDefine.FAMILY_OFFICIAL_MAX_CNT then
        msgErr.msg = Lang.FAMILY_OFFICIAL_LEN_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    officialLen = string.len(fu_leader)
    if officialLen <= 0 or officialLen > FamilyDefine.FAMILY_OFFICIAL_MAX_CNT then
        msgErr.msg = Lang.FAMILY_OFFICIAL_LEN_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    officialLen = string.len(zhanglao)
    if officialLen <= 0 or officialLen > FamilyDefine.FAMILY_OFFICIAL_MAX_CNT then
        msgErr.msg = Lang.FAMILY_OFFICIAL_LEN_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    officialLen = string.len(jingying)
    if officialLen <= 0 or officialLen > FamilyDefine.FAMILY_OFFICIAL_MAX_CNT then
        msgErr.msg = Lang.FAMILY_OFFICIAL_LEN_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    officialLen = string.len(normal)
    if officialLen <= 0 or officialLen > FamilyDefine.FAMILY_OFFICIAL_MAX_CNT then
        msgErr.msg = Lang.FAMILY_OFFICIAL_LEN_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    family.officialName[FamilyDefine.OFFICIAL_LEADER] = leader
    family.officialName[FamilyDefine.OFFICIAL_FU_LEADER] = fu_leader
    family.officialName[FamilyDefine.OFFICIAL_ZHANGLAO] = zhanglao
    family.officialName[FamilyDefine.OFFICIAL_JINGYING] = jingying
    family.officialName[FamilyDefine.OFFICIAL_NORMAL] = normal

    FamilyManager.update(family)

    local msgRet = Msg.gc.GC_FAMILY_OFFICIAL_NAME_CHANGE
    msgRet.leader = leader
    msgRet.fu_leader = fu_leader
    msgRet.zhanglao = zhanglao
    msgRet.jingying = jingying
    msgRet.normal = normal

    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)
end

--军团qq修改
function CG_FAMILY_QQ_CHANGE(human, qq)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or  FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id) or	FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_ZHANGLAO, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    family.qq = qq
    FamilyManager.update(family)

    local msgRet = Msg.gc.GC_FAMILY_QQ_CHANGE
    msgRet.qq = qq
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)

end

--军团sign修改
function CG_FAMILY_SIGN_CHANGE(human, sign)
    sign = GmCommon.filter(sign)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or  FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id) or	FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_ZHANGLAO, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    if family.signtime and family.signtime == os.date("%Y%m%d", os.time()) then
        msgErr.msg = Lang.FAMILY_SIGN_SAMETIME
        Msg.send(msgErr, human.fd)
        return
    end

    local signLen = string.len(sign)
    if signLen < 0 or signLen > FamilyDefine.FAMILY_SIGN_MAX_CNT then
        msgErr.msg = Lang.FAMILY_SIGN_LEN_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    family.sign = sign
    family.signtime = os.date("%Y%m%d", os.time())
    FamilyManager.update(family)

    local msgRet = Msg.gc.GC_FAMILY_SIGN_CHANGE
    msgRet.sign = sign
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)

    local fds = FamilyManager.getOnlineFds(family)
    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_SIGN, family.sign))
end

-- --招募公告
function CG_FAMILY_RECRUIT_CHANGE(human, sign)

    sign = GmCommon.filter(sign)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local signLen = string.len(sign)
    if signLen < 0 or signLen > FamilyDefine.FAMILY_RECRUIT_MAX_CNT then
        msgErr.msg = Lang.FAMILY_RECRUIT_SIGN_LEN_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    family.recruitSign = sign
    FamilyManager.update(family)

    local msgRet = Msg.gc.GC_FAMILY_RECRUIT_CHANGE
    msgRet.sign = sign
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)

end

-- 禅让
function CG_FAMILY_LEADER_CHANGE(human, newLeaderUuid)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if family.extendStartTime then
        msgErr.msg = Lang.FAMILY_NOT_KICK
        Msg.send(msgErr, human.fd)
        return
    end

    if inAllyTime(family.allySrcTime) then
        msgErr.msg = Lang.FAMILY_NO_CHANGE_LEADER_IN_ALLY
        Msg.send(msgErr, human.fd)
        return
    end

    local leader = FamilyManager.getLeader(family)
    if leader.uuid ~= human._id then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local newLeader = FamilyManager.getMember(family, newLeaderUuid)
    if not newLeader then
        msgErr.msg = Lang.FAMILY_TARGET_NOT_IN_FAMILY
        Msg.send(msgErr, human.fd)
        return
    end

    FamilyManager.setOfficial(family, human._id, FamilyDefine.OFFICIAL_NORMAL)
    FamilyManager.setOfficial(family, newLeaderUuid, FamilyDefine.OFFICIAL_LEADER)
    
    MiddleFamilySign.sendFamilyData(family)
    
    local msgRet = Msg.gc.GC_FAMILY_LEADER_CHANGE
    msgRet.newLeaderUuid = newLeaderUuid
    msgRet.oldLeaderUuid = human._id
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)

    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_OFFICIAL_LEADER_OK,
    HtmlUtil.fontName(newLeader.name, newLeader.uuid), OfficialExcel[FamilyDefine.OFFICIAL_LEADER].name))

    nSend2Ldata = nil
    nSend2Ldata = {
        type = 1,
        familyid = family._id,
        familyname = family.familyName,
        newLeaderUuid = newLeaderUuid,
        allyname = getAllyName(family._id),
    }
    InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
end

local function checkOfficial(official)
    for k in ipairs(OfficialExcel) do
        if k == official then
            return true
        end
    end
    return false
end

--官职任命
function CG_FAMILY_OFFICIAL_APPOINT(human, targetUuid, official)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    --check auth
    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    if not checkOfficial(official) then
        msgErr.msg = Lang.FAMILY_OFFICIAL_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    local officialCnt = FamilyManager.getOfficialCnt(family, official)
    if officialCnt >= OfficialExcel[official].officialCnt and official ~= FamilyDefine.OFFICIAL_NORMAL then
        msgErr.msg = Lang.FAMILY_OFFICIAL_CNT_OVER
        Msg.send(msgErr, human.fd)
        return
    end

    local humanMember = FamilyManager.getMember(family, human._id)
    local targetMember = FamilyManager.getMember(family, targetUuid)
    if not targetMember then
        msgErr.msg = Lang.FAMILY_TARGET_NOT_IN_FAMILY
        Msg.send(msgErr, human.fd)
        return
    end

    if humanMember.uuid == targetMember.uuid then
        msgErr.msg = Lang.FAMILY_OFFICIAL_NOT_APPOINT_SELF
        Msg.send(msgErr, human.fd)
        return
    end

    if humanMember.official >= official then
        msgErr.msg = Lang.FAMILY_OFFICIAL_AUTHORITY_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    if targetMember.official == official then
        msgErr.msg = Lang.FAMILY_OFFICIAL_SAME
        Msg.send(msgErr, human.fd)
        return
    end

    if targetMember.official <= humanMember.official then
        msgErr.msg = Lang.FAMILY_OFFICIAL_AUTHORITY_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    FamilyManager.setOfficial(family, targetUuid, official)
    
    if official == FamilyDefine.OFFICIAL_FU_LEADER or official == FamilyDefine.OFFICIAL_LEADER then
        MiddleFamilySign.sendFamilyData(family)
    end

    local msgRet = Msg.gc.GC_FAMILY_OFFICIAL_APPOINT
    msgRet.targetUuid = targetUuid
    msgRet.official = official
    msgRet.officialName = family.officialName[official]
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)

    if official == FamilyDefine.OFFICIAL_LEADER then
        Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_OFFICIAL_LEADER_OK, HtmlUtil.fontName(targetMember.name, targetMember.uuid), OfficialExcel[official].name))
    elseif official == FamilyDefine.OFFICIAL_FU_LEADER then
        Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_OFFICIAL_FU_LEADER_OK, HtmlUtil.fontName(targetMember.name, targetMember.uuid), OfficialExcel[official].name))
    elseif official == FamilyDefine.OFFICIAL_JINGYING then
        Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_OFFICIAL_JINGYING_OK, HtmlUtil.fontName(targetMember.name, targetMember.uuid), OfficialExcel[official].name))
    end


    -- title change
    local target = Human.onlineUuid[targetUuid]
    if target then
        nSend2Ldata = nil
        nSend2Ldata = {
            type = 2,
            familyid = family._id,
            familyname = family.familyName,
            newLeaderUuid = newLeaderUuid,
            allyname = getAllyName(family._id),
        }
        --local titleMsg = Msg.gc.GC_FAMILY_TITLE_CHANGE
        --titleMsg.objID = target.id
        --titleMsg.familyUuid = family._id
        --titleMsg.familyName = family.familyName
        --titleMsg.familyOfficial = official
        --titleMsg.allyName = getAllyName(family._id)
        --Obj.sendArea(titleMsg, target.scene_id, target.x, target.y)

        --InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
    end

    FamilyManager.onApplyCntChange(family)
end

--取军团经验
function getAddFamilyExp(family, addFamilyExp)
    local os_time = os.time()
    if not Util.isSameDay(family.dailyFamilyExpTime) then
        family.dailyFamilyExpTime = os_time
        family.dailyFamilyExp = nil
        return math.min(BuildingExcel[family.familyLv].dailyFamilyExpMax, addFamilyExp)
    else
        local nowFamilyExp = family.dailyFamilyExp or 0
        local leftFamilyExp = BuildingExcel[family.familyLv].dailyFamilyExpMax - nowFamilyExp
        return math.min(leftFamilyExp, addFamilyExp)
    end
end

--　奖励条件逻辑
function checkCondition(human)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    local conf = BuildingExcel[family.familyLv]
    local getCnt = human.db.familyRewardGetCnt or 0
    local getCntMax = conf.rewardCnt

    if getCnt >= getCntMax then
        msgErr.msg = Lang.FAMILY_REWARD_GET_CNT_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    local nowContribution = human.db.familyContribution
    local needContribution = CreateExcel[1].rewardNeedContribution

    if nowContribution < needContribution then
        msgErr.msg = Lang.FAMILY_CONTRIBUTION_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    return true
end

-- 奖励扣除物品逻辑
--function delNeed(human, lottery_id, conf)
--
--    local family = FamilyManager.findByUuid(human.familyUuid)
--
--    if not human.db.familyRewardGetCnt then
--        human.db.familyRewardGetCnt = 0
--    end
--
--    human.db.familyRewardGetCnt = human.db.familyRewardGetCnt + 1
--
--    local msgCnt = Msg.gc.GC_FAMILY_REWARD_CNT
--    msgCnt.getCnt = human.db.familyRewardGetCnt
--    Msg.send(msgCnt, human.fd)
--
--    if not human.db.familyRewardGetTime then
--        human.db.familyRewardGetTime = os.time()
--    end
--
--    local needContribution = CreateExcel[1].rewardNeedContribution
--    updateFamilyContribution(human, -needContribution)
--    sendContribution(human, family)
--
--end

function getFamilyLottery(human)
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return 0
    end
    local conf = BuildingExcel[family.familyLv]
    local getCnt = human.db.familyRewardGetCnt or 0
    local getCntMax = conf.rewardCnt
    if getCnt >= getCntMax then
        return 0
    end
    local rewardNeedContribution = CreateExcel[1].rewardNeedContribution
    if human.db.familyContribution < rewardNeedContribution then
        return 0
    end
    return 1
end

--function CG_FAMILY_REWARD_CONF_QUERY(human)
--
--    local msgErr = Msg.gc.GC_BROADCAST
--    msgErr.type = Lang.MOUSE
--
--    local family = FamilyManager.findByUuid(human.familyUuid)
--    if not family then
--        msgErr.msg = Lang.FAMILY_NOT_EXIST
--        Msg.send(msgErr, human.fd)
--        return
--    end
--
--    local conf = BuildingExcel[family.familyLv]
--    local msgRet = Msg.gc.GC_FAMILY_REWARD_CONF_QUERY
--    msgRet.getCnt = human.db.familyRewardGetCnt or 0
--    msgRet.getCntMax = conf.rewardCnt
--    msgRet.rewardNeedContribution = CreateExcel[1].rewardNeedContribution
--    LotteryLogic.makeLotteryData(msgRet.lotteryData, conf.rewardID)
--    Msg.send(msgRet, human.fd)
--
--end

local function hasStudy(human, skillType)
    if not human.db.familySkill then
        return 0
    end
    if not human.db.familySkill[skillType] then
        return 0
    end
    return 1
end
-- 军团仓库查询
function CG_FAMILY_STORE_LIST(human)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end
    local msgList = Msg.gc.GC_FAMILY_STORE_LIST
    local cap = BuildingExcel[family.familyLv].storeOpenCnt
    msgList.cap = cap
    Grid.makeList(human, family.store, cap, msgList, Msg.gc.GC_FAMILY_STORE_CLEAR)

    --local nSend2Ldata = nil
    --nSend2Ldata = {
    --    type = 4,
    --    data = {familystore = family.store, cap = BuildingExcel[family.familyLv].storeOpenCnt, familystoreLen = family.storeLen}
    --}
    --InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
end

-- 查询军团仓库记录
function CG_FAMILY_STORE_RECORD_QUERY(human)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end
    local msgRet = Msg.gc.GC_FAMILY_STORE_RECORD_QUERY
    msgRet.records[0] = 0

    for i=#family.storeRecord, 1, -1 do
        if msgRet.records[0] >= #msgRet.records then
            break
        end
        local record = family.storeRecord[i]
        msgRet.records[0] = msgRet.records[0] + 1
        wrapperFamilyStoreRecord(msgRet.records[msgRet.records[0]], record)
    end
    Msg.send(msgRet, human.fd)
end

--检查仓库格子下标
function checkIndex(family, storeIndex)
    local storeOpenCnt = BuildingExcel[family.familyLv].storeOpenCnt
    if storeIndex < 0 or storeIndex >= storeOpenCnt then
        return false
    end
    return true
end

local function sendFamilyItemChange(family, index, fds)
    local grid = family.store[index]
    local msgItemChange = Msg.gc.GC_FAMILY_STORE_ITEM_CHANGE
    Grid.makeItem(grid, msgItemChange.itemData, index)
    Msg.sendMulti(msgItemChange, fds)
end


function checkCanAddItem(family, tGrid)
    local id = tGrid.id
    local bind = tGrid.bind
    local cnt = tGrid.cnt
    local lifeTime = tGrid.lifeTime
    local open = tGrid.open

    local bag = family.store
    local storeOpenCnt = BuildingExcel[family.familyLv].storeOpenCnt
    local capPerGrid = ItemDefine.CAP_PER_GRID
    for i = 0, storeOpenCnt - 1 do
        local grid = bag[i]
        if not grid or grid.id == 0 or grid.open == open and grid.id == id and grid.bind == bind and grid.lifeTime == lifeTime and grid.cnt < capPerGrid and ItemDefine.canAppend(grid.id) then
            if not ItemDefine.canAppend(id) then
                cnt = cnt - 1
            else
                if not grid or grid.id == 0 then
                    cnt = cnt - capPerGrid
                else
                    cnt = cnt - (capPerGrid - grid.cnt)
                end
            end
            if cnt <= 0 then
                return true
            end
        end
    end
end

local pos = pos or {}
local function addItem(family, tGrid)

    local id = tGrid.id
    local bind = tGrid.bind
    local cnt = tGrid.cnt
    local lifeTime = tGrid.lifeTime
    local open = tGrid.open

    if not checkCanAddItem(family, tGrid) then
        return
    end

    local cap = BuildingExcel[family.familyLv].storeOpenCnt
    local bag = family.store
    local capPerGrid = ItemDefine.CAP_PER_GRID
    local posLen = 0
    local grid
    for i = 0, cap do
        grid = bag[i]
        if grid and grid.open == open and grid.id == id and grid.bind == bind and grid.cnt < capPerGrid and ItemDefine.canAppend(grid.id) and grid.lifeTime == lifeTime then
            posLen = posLen + 1
            pos[posLen] = i
            local cntReal = math.min(capPerGrid - grid.cnt, cnt)
            if not ItemDefine.canAppend(id) then
                cntReal = 1
            end
            grid.cnt = grid.cnt + cntReal
            cnt = cnt - cntReal
            if cnt <= 0 then
                break
            end
        end
    end

    if cnt > 0 then
        for i = 0, cap do
            grid = bag[i]
            if not grid or grid.id == 0 then
                posLen = posLen + 1
                pos[posLen] = i
                local cntReal = math.min(capPerGrid, cnt)
                if not ItemDefine.canAppend(id) then
                    cntReal = 1
                end
                local newGrid = {}
                Grid.copy(newGrid, tGrid)
                newGrid.open = open
                newGrid.cnt = cntReal
                bag[i] = newGrid
                cnt = cnt - cntReal
                family.storeLen = family.storeLen + 1
                if cnt <= 0 then
                    break
                end
            end
        end
    end

    local fds = FamilyManager.getOnlineFds(family)
    for i = 1 , posLen do
        sendFamilyItemChange(family, pos[i], fds, tGrid)
    end
    return true
end

-- 军团仓库add物品
function familyStoreAddItem(family, human, oData)
    oData.data.bagGrid.open = 0
    addItem(family, oData.data.bagGrid)

    local record = FamilyManager.addStoreRecord(family, human, oData.data.bagGrid, FamilyDefine.FAMILY_STORE_RECORD_PUT)
    FamilyManager.update(family)

    local msgRecord = Msg.gc.GC_FAMILY_STORE_RECORD_ADD
    local content = wrapperFamilyStoreRecord(msgRecord.record, record)
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRecord, fds)
    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, content)
    return true
end

function familyStoreDelItem(family, human, storeGrid, cnt, storeIndex)
    storeGrid.cnt = storeGrid.cnt - cnt
    local newStoreGrid = {}
    Util.copyTable(storeGrid, newStoreGrid)
    if storeGrid.cnt < 1 then
        family.store[storeIndex].id = 0
        family.storeLen = family.storeLen - 1
    end

    newStoreGrid.cnt = cnt
    newStoreGrid.open = nil

    local record = FamilyManager.addStoreRecord(family, human, newStoreGrid, FamilyDefine.FAMILY_STORE_RECORD_GET)
    FamilyManager.update(family)

    local msgRecord = Msg.gc.GC_FAMILY_STORE_RECORD_ADD
    local content = wrapperFamilyStoreRecord(msgRecord.record, record)
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRecord, fds)

    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, content)

    local msgItemChange = Msg.gc.GC_FAMILY_STORE_ITEM_CHANGE
    Grid.makeItem(storeGrid, msgItemChange.itemData, storeIndex)
    Msg.sendMulti(msgItemChange, fds)
    return true
end

-- 军团仓库格子open
function CG_FAMILY_STORE_ITEM_OPEN(human, storeIndex, state)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if not (state == FamilyDefine.STORE_GRID_STATE_CLOSE or state == FamilyDefine.STORE_GRID_STATE_OPEN) then
        msgErr.msg = Lang.FAMILY_STORE_GRID_STATE
        Msg.send(msgErr, human.fd)
        return
    end

    local storeIndexOK = checkIndex(family, storeIndex)
    if not storeIndexOK then
        msgErr.msg = Lang.FAMILY_STORE_INDEX_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_ZHANGLAO, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local storeGrid = family.store[storeIndex]
    if not storeGrid then
        msgErr.msg = Lang.FAMILY_STORE_INDEX_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    if (state == FamilyDefine.STORE_GRID_STATE_OPEN and state == storeGrid.open) or (state == FamilyDefine.STORE_GRID_STATE_CLOSE and not storeGrid.open) then
        return
    end

    local content = nil
    if state == FamilyDefine.STORE_GRID_STATE_OPEN then
        storeGrid.open = 1
        content = string.format(Lang.FAMILY_STORE_GRID_OPEN, HtmlUtil.fontName(human.name, human._id), HtmlUtil.fontItem(storeGrid))
    else
        storeGrid.open = 0
        content = string.format(Lang.FAMILY_STORE_GRID_CLOSE, HtmlUtil.fontName(human.name, human._id), HtmlUtil.fontItem(storeGrid))
    end

    FamilyManager.update(family)

    local msgItemChange = Msg.gc.GC_FAMILY_STORE_ITEM_CHANGE
    Grid.makeItem(storeGrid, msgItemChange.itemData, storeIndex)
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgItemChange, fds)

    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, content)
end

-- 军团仓库格子交换
function CG_FAMILY_STORE_ITEM_SWAP(human, srcIndex, tarIndex)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if	not	(FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id)
        or  FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)
        or	FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_ZHANGLAO, human._id)
        )then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local srcIndexOK = checkIndex(family, srcIndex)
    local tarIndexOK = checkIndex(family, tarIndex)
    local srcGrid = family.store[srcIndex]
    if not srcIndexOK or not tarIndexOK or not srcGrid then
        msgErr.msg = Lang.FAMILY_STORE_INDEX_INVALID
        Msg.send(msgErr, human.fd)
        return
    end

    family.store[srcIndex], family.store[tarIndex] = family.store[tarIndex], family.store[srcIndex]
    FamilyManager.update(family)

    local msgItemChange = Msg.gc.GC_FAMILY_STORE_ITEM_CHANGE
    local fds = FamilyManager.getOnlineFds(family)
    Grid.makeItem(family.store[srcIndex], msgItemChange.itemData, srcIndex)
    Msg.sendMulti(msgItemChange, fds)

    Grid.makeItem(family.store[tarIndex], msgItemChange.itemData, tarIndex)
    Msg.sendMulti(msgItemChange, fds)

end

-- 军团仓库整理
function CG_FAMILY_STORE_SORT(human)

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return
    end

    local isOfficial = FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id)
    or  FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)
    or	FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_ZHANGLAO, human._id)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    if not isOfficial then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local cap = BuildingExcel[family.familyLv].storeOpenCnt
    Grid.sort(family.store, cap)

    --local fds = FamilyManager.getOnlineFds(family)
    --local msgRet = Msg.gc.GC_FAMILY_STORE_SORT
    --Msg.sendMulti(msgRet, fds)

    local fds = FamilyManager.getOnlineFds(family)
    local msgList = Msg.gc.GC_FAMILY_STORE_LIST
    msgList.cap = cap
    Grid.makeList(human, family.store, cap, msgList, Msg.gc.GC_FAMILY_STORE_CLEAR, fds)
    
    --local nSend2Ldata = nil
    --nSend2Ldata = {
    --    type = 4,
    --    data = {familystore = family.store, cap = BuildingExcel[family.familyLv].storeOpenCnt, familystoreLen = family.storeLen}
    --}
    --InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
end




--军团军旗进阶
function CG_FAMILY_BANNER_UP(human)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end
    getFamilyExtendOpen(family)

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    if family.familyBanner >= family.familyLv then
        msgErr.msg = Lang.FAMILY_FLAG_LVUP_UP
        Msg.send(msgErr, human.fd)
        return
    end

    if family.familyBanner >= #BannerExcel then
        msgErr.msg = Lang.FAMILY_FLAG_LVUP_MAXLV
        Msg.send(msgErr, human.fd)
        return
    end

    local confg = BannerExcel[family.familyBanner]
    --if conf.needExp == 0 then
    --    msgErr.msg = Lang.FAMILY_FAMILY_MAX_LV
    --    Msg.send(msgErr, human.fd)
    --    return
    --end

    if confg and confg.needmoney > family.familyMoney then
        msgErr.msg = Lang.FAMILY_FAMILY_MONEY_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    local costFamilyMoney = 0
    local costItemData = {}
    local nLevUp = 0
    local nItemEnought = true
    local nMoneynought = true
    for i = (family.familyBanner + 1), #BannerExcel do
        if family.familyMoney - costFamilyMoney < BannerExcel[i].needmoney then
            nMoneynought = false
            break
        else
            costFamilyMoney = costFamilyMoney + BannerExcel[i].needmoney
        end

        for k, v in ipairs(BannerExcel[i].itemdata) do
            if ((family.FamilyBannerItemData[v[1]] or 0) - (costItemData[v[1]] or 0)) < v[2] then
                nItemEnought = false
                break
            else
                costItemData[v[1]] = (costItemData[v[1]] or 0) + v[2]
            end
        end

        if nItemEnought and nMoneynought and (family.familyBanner + 1 <= #BannerExcel) then
            nLevUp = nLevUp + 1
            nItemEnought = true
            nMoneynought = true
            break       --此处控制是否要连续升阶
        else
            break
        end
    end

    if nLevUp > 0 then
        if costFamilyMoney > 0 then
            family.familyMoney = family.familyMoney - costFamilyMoney
        end

        for k, v in pairs(costItemData) do
            local nRemain = family.FamilyBannerItemData[k] - v
            family.FamilyBannerItemData[k] = nRemain < 0 and 0 or nRemain
        end

        family.familyBanner = family.familyBanner + nLevUp

        FamilyManager.update(family)
        sendFamilyUpdate(family)

        --msgErr.msg = string.format(Lang., family.familyBanner)
        --Msg.send(msgErr, human.fd)

        local msgRet = Msg.gc.GC_FAMILY_BANNER_UP
        msgRet.banner = family.familyBanner
        local fds = FamilyManager.getOnlineFds(family)
        Msg.sendMulti(msgRet, fds)

        local nSend2Ldata = {
            type = 12,
            familyUuid = family._id,
            bannerlv = family.familyBanner,
            memberList = family.memberList,
        }
        InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
        Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_FLAG_LVUP_OK, family.familyBanner))
        Log.write(Log.LOGID_OSS_FAMILY_INFO, family._id, family.familyName, human.name, FamilyManager.getLeader(family).name or "", family.familyLv, family.familyMoney, family.familyBanner)
    else
        if nItemEnought == false then
            msgErr.msg = Lang.FAMILY_FLAG_LVUP_NOENOUGHTITEM
        else
            msgErr.msg = Lang.FAMILY_FLAG_LVUP_NOENOUGHTMONEY
        end
        Msg.send(msgErr, human.fd)
    end
end

--军团招募
function CG_FAMILY_RECRUIT(human)

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    if not (FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_FU_LEADER, human._id) or FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_ZHANGLAO, human._id)) then
        msgErr.msg = Lang.FAMILY_NOT_LEADER
        Msg.send(msgErr, human.fd)
        return
    end

    local needFamilyMoney = CreateExcel[1].recruitFamilyMoney
    if family.familyMoney < needFamilyMoney then
        msgErr.msg = Lang.FAMILY_FAMILY_MONEY_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    local now = os.time()
    if family.recruitTime then
        local leftTime = CreateExcel[1].recruitCD - now + family.recruitTime
        if leftTime > 0 then
            msgErr.msg = string.format(Lang.FAMILY_RECRUIT_IN_CD, leftTime)
            Msg.send(msgErr, human.fd)
            return
        end
    end

    local data = HtmlUtil.TYPE_ACTION_ON_FAMILY_APPLY .."|"..family._id
    local tip = string.format(Lang.FAMILY_RECRUIT_TIP1, HtmlUtil.font("["..family.familyName.."]", "#FF00FF"))
    tip = tip .. HtmlUtil.fontAFlagU(data, HtmlUtil.font(Lang.FAMILY_RECRUIT_TIP2, "#00FF00"))
    Broadcast.sendBroadcast2World(Lang.ADVERTISE, tip)

    family.recruitTime = now
    family.familyMoney = family.familyMoney - needFamilyMoney
    FamilyManager.update(family)
    sendFamilyUpdate(family)

end


-- 取官职名
function getOfficeName(uuid, familyUuid, isNick)

    if not uuid or not familyUuid then
        return
    end

    local family = FamilyManager.findByUuid(familyUuid)
    if not family then
        return
    end

    local member = FamilyManager.getMember(family, uuid)
    if not member then
        return
    end

    if isNick then
        return family.officialName[member.official]
    else
        return OfficialExcel[member.official].name
    end

end

function CG_FAMILY_CONTRIBUTE_QUERY(human)
    local msgRet = Msg.gc.GC_FAMILY_CONTRIBUTE
    msgRet.uuid = human._id
    msgRet.familyContribution = human.db.familyContribution
    msgRet.familyAlgContributionRmb = human.db.familyAlgContributionRmb
    msgRet.familyContributionSum = 0
    local family = FamilyManager.findByUuid(familyUuid)
    if family then
        local humanMember = FamilyManager.getMember(family, human._id)
        if humanMember and humanMember.familyContributionSum then
            msgRet.familyContributionSum = humanMember.familyContributionSum
        end
    end
    Msg.send(msgRet, human.fd)
end

function getFamilyExtendOpen(family)
    local open = 0
    if family.extendStartTime then
        local time = Util.getInterval(family.extendStartTime)
        if time > 0 and time < 86400 then
            open = 1
        end
    end
    return open
end

function CG_FAMILY_EXTEND_OPEN_QUERY(human)
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return
    end
    local msgRet = Msg.gc.GC_FAMILY_EXTEND_OPEN_QUERY
    msgRet.open = getFamilyExtendOpen(family)
    Msg.send(msgRet, human.fd)

end

function CG_FAMILY_EXTEND(human)

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return
    end

    local open = getFamilyExtendOpen(family)
    if open == 0 then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_EXTEND_NOT_OPEN)
        return
    end

    if FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_EXTEND)
        return
    end

    if not family.extends then
        family.extends = {}
    end

    -- check double extend
    if family.extends[human._id] then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_DOUBLE_EXTEND)
        return
    end

    family.extends[human._id] = os.time()
    FamilyManager.update(family)
    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_EXTEND_OK)

end

function newLeader(family)

    local newLeaderUuid = nil
    local newLeaderContribution = 0
    local newLeaderJoinTime = 0
    local oldLeader = FamilyManager.getLeader(family)

    if family.extends then
        for uuid , time in pairs(family.extends) do
            local member = FamilyManager.getMember(family, uuid)
            if member then
                if (member.familyContributionSum > newLeaderContribution) or (newLeaderContribution ~= 0 and member.familyContributionSum == newLeaderContribution and time < newLeaderJoinTime) then
                    newLeaderContribution = member.familyContributionSum
                    newLeaderUuid = uuid
                    newLeaderJoinTime = time
                end
            end
        end
    end

    -- check contribution and time
    if not newLeaderUuid then
        for _, member in ipairs(family.memberList) do
            if member.uuid ~= oldLeader.uuid then
                if member.familyContributionSum >= newLeaderContribution then
                    newLeaderContribution = member.familyContributionSum
                    newLeaderUuid = member.uuid
                end
            end
        end
    end

    -- 找不到继承者返回
    if not newLeaderUuid then
        family.extendStartTime = nil
        family.extends = nil
        family.extendTipFlag = nil
        FamilyManager.update(family)
        return
    end

    local newLeader = FamilyManager.getMember(family, newLeaderUuid)

    FamilyManager.setOfficial(family, oldLeader.uuid, FamilyDefine.OFFICIAL_NORMAL)
    FamilyManager.setOfficial(family, newLeaderUuid, FamilyDefine.OFFICIAL_LEADER)
    MiddleFamilySign.sendFamilyData(family)
    
    local msgRet = Msg.gc.GC_FAMILY_LEADER_CHANGE
    msgRet.newLeaderUuid = newLeaderUuid
    msgRet.oldLeaderUuid = oldLeader.uuid
    local fds = FamilyManager.getOnlineFds(family)
    Msg.sendMulti(msgRet, fds)

    -- title change 1
    --local oldHuman = Human.onlineUuid[oldLeader.uuid]
    --local titleMsg = Msg.gc.GC_FAMILY_TITLE_CHANGE
    --if oldHuman then
    --    titleMsg.objID = oldHuman.id
    --    titleMsg.familyUuid = family._id
    --    titleMsg.familyName = family.familyName
    --    titleMsg.familyOfficial = FamilyDefine.OFFICIAL_NORMAL
    --    titleMsg.allyName = getAllyName(family._id)
    --    Obj.sendArea(titleMsg, oldHuman.scene_id, oldHuman.x, oldHuman.y)
    --end

    ---- title change 2
    --local newHuman = Human.onlineUuid[newLeaderUuid]
    --if newHuman then
    --    titleMsg.objID = newHuman.id
    --    titleMsg.familyUuid = family._id
    --    titleMsg.familyName = family.familyName
    --    titleMsg.familyOfficial = FamilyDefine.OFFICIAL_LEADER
    --    titleMsg.allyName = getAllyName(family._id)
    --    Obj.sendArea(titleMsg, newHuman.scene_id, newHuman.x, newHuman.y)
    --end

    family.extendStartTime = nil
    family.extends = nil
    family.extendTipFlag = nil
    FamilyManager.update(family)

    local fds = FamilyManager.getOnlineFds(family)
    local msgRet = Msg.gc.GC_FAMILY_LEADER_CHANGE
    msgRet.newLeaderUuid = newLeader.uuid
    msgRet.oldLeaderUuid = oldLeader.uuid
    Msg.sendMulti(msgRet, fds)

    -- tip
    local tip = string.format(Lang.FAMILY_EXTEND_OK2, HtmlUtil.fontName(newLeader.name, newLeader.uuid), family.familyName)
    Broadcast.sendBroadcast2World(Lang.GROSSIP+Lang.UP, tip)

    local content = string.format(Lang.FAMILY_EXTEND_MAIL_CONTENT3, HtmlUtil.fontName(newLeader.name, newLeader.uuid))
    for _, member in ipairs(family.memberList) do
        MailLogicFW.addSystemMessage(member.uuid, Lang.FAMILY_EXTEND_MAIL_TITLE3, content)
    end

    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_EXTEND_OK1, HtmlUtil.fontName(newLeader.name, newLeader.uuid)))

end

-- 继承timer
function extend()
    for uuid, family in pairs(FamilyManager.uuid2Family) do
        if not family.extendStartTime then
            if #family.memberList > 1 then
                local leader = FamilyManager.getLeader(family)
                if leader then
                    local target = Human.onlineUuid[leader.uuid]
                    if not target or not target.fd then
                        if leader.lastLogOutTime > 0 then
                            local time = Util.getInterval(leader.lastLogOutTime)
                            if time >= FamilyDefine.FAMILY_EXTEND_TIME then	-- 大于7天
                                if not family.lastExtendStartTime or Util.getInterval(family.lastExtendStartTime) >= FamilyDefine.FAMILY_EXTEND_ROUNDTIME  then		-- 继承间隔3天
                                    family.extendStartTime = os.time()
                                    family.lastExtendStartTime = family.extendStartTime
                                    family.extendTipFlag = {}
                                    FamilyManager.update(family)
                                    -- 继承开始
                                    -- send mail
                                    local content = string.format(Lang.FAMILY_EXTEND_MAIL_CONTENT1, HtmlUtil.fontName(leader.name, leader.uuid))
                                    for _, member in ipairs(family.memberList) do
                                        if member.uuid ~= leader.uuid then -- 成员
                                            MailLogicFW.addSystemMessage(member.uuid, Lang.FAMILY_EXTEND_MAIL_TITLE1, content)
                                        else--族长
                                            MailLogicFW.addSystemMessage(member.uuid, Lang.FAMILY_EXTEND_MAIL_TITLE2, Lang.FAMILY_EXTEND_MAIL_CONTENT2)
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
        else
            local now = os.time()
            local time = now - family.extendStartTime
            if time >= FamilyDefine.FAMILY_EXTEND_NEWLEADER then	--大于一天
                newLeader(family)
            else
                local hour = math.floor(time/3600)
                if hour ~= 0 and not family.extendTipFlag[hour] then
                    family.extendTipFlag[hour] = true
                    FamilyManager.update(family)
                    local fds = FamilyManager.getOnlineFds(family)
                    Broadcast.sendBroadcastFDs(fds, Lang.FAMILY, string.format(Lang.FAMILY_EXTEND_START_TIP, 24-hour))
                end
            end
        end
    end
end

-- 是否在同盟的有效时间内
function inAllyTime(time)
    if not time then
        return
    end
    local now = os.time()
    local t = now - time
    if t >= CreateExcel[1].allyCD then	--24h
        return
    else
        return true
    end
end

function CG_FAMILY_ALLY(human, familyUuid)
    local targetFamily = FamilyManager.findByUuid(familyUuid)
    if not targetFamily then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_INVALID_UUID)
        return
    end

    if FamilyManager.getAlly(targetFamily._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_TARGET_HAS_ALLY)
        return
    end

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_NO_FAMILY)
        return
    end

    if FamilyManager.getAlly(family._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_HAS_ALLY)
        return
    end

    if targetFamily._id == family._id then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_NO_SELF)
        return
    end

    if not FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_LEADER)
        return
    end

    if inAllyTime(family.allyTargetTime) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_SELF)
        return
    end

    if inAllyTime(family.allySrcTime) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_SELF)
        return
    end

    if inAllyTime(targetFamily.allyTargetTime) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_TARGET)
        return
    end

    if inAllyTime(targetFamily.allySrcTime) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_TARGET)
        return
    end

    local targetLeader = FamilyManager.getLeader(targetFamily)
    local targetHuman = Human.onlineUuid[targetLeader.uuid]
    if not targetHuman or not targetHuman.fd then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_TARGET_LEADER_NOT_ONLINE)
        return
    end

    if family.familyMoney < CreateExcel[1].allyFamilyMoney then
        Broadcast.sendBroadcast(human, Lang.MOUSE, string.format(Lang.FAMILY_ALLY_NOT_ENOUGH_MONEY, CreateExcel[1].allyFamilyMoney))
        return
    end

    updateFamilyMoney(family, -CreateExcel[1].allyFamilyMoney, true)

    local now = os.time()
    family.allyTargetTime = now
    family.allyTargetUuid = targetFamily._id
    FamilyManager.update(family)

    targetFamily.allySrcUuid = family._id
    targetFamily.allySrcTime = now
    FamilyManager.update(targetFamily)

    local msgRet = Msg.gc.GC_FAMILY_ALLY
    msgRet.familyUuid = family._id
    msgRet.familyName = family.familyName
    Msg.send(msgRet, targetHuman.fd)

    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_SEND_ALLY_OK)

end

function onAllyTitle(family)
    local titleMsg = Msg.gc.GC_FAMILY_TITLE_CHANGE
    for _, member in ipairs(family.memberList) do
        local target = Human.onlineUuid[member.uuid]
        if target and target.fd then
            titleMsg.objID = target.id
            titleMsg.familyUuid = family._id
            titleMsg.familyName = family.familyName
            titleMsg.familyOfficial = member.official
            titleMsg.allyName = getAllyName(family._id)
            Obj.sendArea(titleMsg, target.scene_id, target.x, target.y)
        end
    end
end

function onRefuseByLoginOut(human)
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return
    end
    if inAllyTime(family.allySrcTime) then
        allyAgree(human, family.allySrcUuid)
    end
end

function allyAgree(human, familyUuid, agree)

    if FamilyWar2.FAMILY_WAR_FIGHTING_FLAG then
        if agree then
            Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_FAIL_IN_FAMILY_WAR)
        end
        agree = nil
    end

    local targetFamily = FamilyManager.findByUuid(familyUuid)
    if not targetFamily then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_INVALID_UUID)
        return
    end

    if FamilyManager.getAlly(targetFamily._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_TARGET_HAS_ALLY)
        return
    end

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_NO_FAMILY)
        return
    end

    if FamilyManager.getAlly(family._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_HAS_ALLY)
        return
    end

    if not FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_LEADER)
        return
    end

    if not inAllyTime(family.allySrcTime) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_NOT_IN_TIME)
        return
    end

    if family.allySrcUuid ~= targetFamily._id then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_AGREE_ID_NOT_MATCH)
        return
    end

    if agree then
        family.allyUuid = targetFamily._id
        targetFamily.allyUuid = family._id
        family.allyTargetUuid = nil
        family.allyTargetTime = nil
        targetFamily.allySrcUuid = nil
        targetFamily.allySrcTime = nil
        Broadcast.sendBroadcast2World(Lang.GROSSIP+Lang.UP, string.format(Lang.FAMILY_ALLY_OK, HtmlUtil.font(family.familyName, "#DB19DA"), HtmlUtil.font(targetFamily.familyName, "#DB19DA")))
        onAllyTitle(family)
        onAllyTitle(targetFamily)
    else
        Broadcast.sendBroadcast2World(Lang.GROSSIP+Lang.UP, string.format(Lang.FAMILY_ALLY_FAIL, HtmlUtil.font(family.familyName, "#DB19DA"), HtmlUtil.font(targetFamily.familyName, "#DB19DA")))
    end

    family.allySrcUuid = nil
    family.allySrcTime = nil
    targetFamily.allyTargetUuid = nil
    targetFamily.allyTargetTime = nil

    FamilyManager.update(family)
    FamilyManager.update(targetFamily)

end

function CG_FAMILY_ALLY_AGREE(human, familyUuid)
    allyAgree(human, familyUuid, true)
end

function CG_FAMILY_ALLY_REFUSE(human, familyUuid)
    allyAgree(human, familyUuid)
end

function allyBreak(family)
    local ally = FamilyManager.getAlly(family._id)
    if not ally then
        return
    end
    if ally then
        ally.allyUuid = nil
        FamilyManager.update(ally)
    end

    family.allyUuid = nil
    FamilyManager.update(family)

    onAllyTitle(family)
    onAllyTitle(ally)

    Broadcast.sendBroadcast2World(Lang.GROSSIP+Lang.UP, string.format(Lang.FAMILY_ALLY_BREAK, HtmlUtil.font(family.familyName, "#DB19DA"), HtmlUtil.font(ally.familyName, "#DB19DA")))

end

function CG_FAMILY_ALLY_BREAK(human)
    if FamilyWar2.FAMILY_WAR_FIGHTING_FLAG then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_IN_FAMILY_WAR)
        return
    end

    if StarWarReady.checkIsActivity() then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_IN_FAMILY_STARWAR)
        return
    end

    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_ALLY_NO_FAMILY)
        return
    end

    if not FamilyManager.isOfficial(family, FamilyDefine.OFFICIAL_LEADER, human._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_LEADER)
        return
    end

    if not FamilyManager.getAlly(family._id) then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_HAS_NO_ALLY)
        return
    end

    allyBreak(family)
end


function CG_FAMILY_AUTO_APPLY_AGREE(human, state)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end

    local member = FamilyManager.getMember(family, human._id)
    if member.official ~= FamilyDefine.OFFICIAL_LEADER and member.official ~= FamilyDefine.OFFICIAL_FU_LEADER then
        msgErr.msg = Lang.FAMILY_OFFICIAL_AUTHORITY_NOT_ENOUGH
        Msg.send(msgErr, human.fd)
        return
    end

    family.familyApplyState = (state == 1 and 1 or 0)
    FamilyManager.update(family)
    local msgRet = Msg.gc.GC_FAMILY_AUTO_APPLY_AGREE
    msgRet.state = family.familyApplyState
    Msg.send(msgRet, human.fd)
end


local function notifyCostYuanbao(human, succ)
    local nSend2Ldata = {
            type = 13,
            result = succ,
    }
    InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
end

function checkFamilyCopyIsOpen(familyUuid, copyID)
    local match = CopyW.family2Copy[familyUuid]
    if not match then
        return
    end
    if match[copyID] then
        return true
    end
    for copy, info in pairs(match) do
        if CopyCommon.isSameGroupCopy(copyID, copy) then
            return true
        end   
    end
end

function CG_FAMILY_ACT_COPY_START(human, type)
    local copyID = CopyDefine.COPY_FAMILY_COPY_ID[type]
    if not copyID then
        if type == 2 then
            notifyCostYuanbao(human, 0)
        end
        return
    end
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        if type == 2 then
            notifyCostYuanbao(human, 0)
        end
        return
    end
    local member = FamilyManager.getMember(family, human._id)
    if not member then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        if type == 2 then
            notifyCostYuanbao(human, 0)
        end
        return
    end
    local err = CopyCommon.checkEnterCondition(human, copyID)
    if err then
        msgErr.msg = err
        Msg.send(msgErr, human.fd)
        if type == 2 then
            notifyCostYuanbao(human, 0)
        end
        return
    end
    if member.official ~= FamilyDefine.OFFICIAL_LEADER and member.official ~= FamilyDefine.OFFICIAL_FU_LEADER then
        msgErr.msg = Lang.FAMILY_COPY_NEED_LEADER
        Msg.send(msgErr, human.fd)
        if type == 2 then
            notifyCostYuanbao(human, 0)
        end
        return
    end
    if family.familyCopyTimes >= 2 then
        msgErr.msg = Lang.FAMILY_COPY_HAD_FINISH
        Msg.send(msgErr, human.fd)
        if type == 2 then
            notifyCostYuanbao(human, 0)
        end
        return
    end
    if checkFamilyCopyIsOpen(family._id, copyID) then
        msgErr.msg = Lang.FAMILY_COPY_HAD_START                
        Msg.send(msgErr, human.fd)   
        if type == 2 then
            notifyCostYuanbao(human, 0)
        end     
        return
    end
    
    if type == 1 and family.familyMoney < FamilyDefine.FAMILY_COPY_MONEY then
        msgErr.msg = Lang.FAMILY_COPY_NO_MONEY                
        Msg.send(msgErr, human.fd)   
        return
    end
    
    if type == 1 then
        family.familyMoney = family.familyMoney - FamilyDefine.FAMILY_COPY_MONEY
    else
        notifyCostYuanbao(human, 1) 
    end
    
    CopyW.family2Copy[family._id] = CopyW.family2Copy[family._id] or {}
    CopyW.family2Copy[family._id][copyID] = CopyW.family2Copy[family._id][copyID] or {}
    CopyW.sendApplyRoom(human._id, copyID, Timer.now)
--    msgErr.msg = Lang.FAMILY_COPY_HAD_START
--    Msg.send(msgErr, human.fd)
end

function sendFamilyTitle(family)
    local msg = Msg.gc.GC_TITLE_EFFECT
    msg.title = 0
    if FamilyWarTequan[family.middleFamilyResult] then
        msg.title = FamilyWarTequan[family.middleFamilyResult].titleID
    end
    FamilyManager.sendFamily(msg, family)
    
    local nSend2Ldata = {
            type = 15,
    }
    InnerDataManagerFW.Send2LInnerData(nil, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)    
end

function CG_FAMILY_WAR_JOIN(human, uuid)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end
    local member = FamilyManager.getMember(family, human._id)
    if not member then
        msgErr.msg = Lang.FAMILY_NOT_EXIST
        Msg.send(msgErr, human.fd)
        return
    end
    local target = FamilyManager.getMember(family, uuid)
    if not target then
        msgErr.msg = Lang.FAMILY_WAR_NO_MEMBER
        Msg.send(msgErr, human.fd)
        return
    end
    if member.official ~= FamilyDefine.OFFICIAL_LEADER and member.official ~= FamilyDefine.OFFICIAL_FU_LEADER then
        msgErr.msg = Lang.FAMILY_WAR_NO_OFFICE_SET
        Msg.send(msgErr, human.fd)
        return
    end
    if MiddleFamilySign.isWarTime() then
        msgErr.msg = Lang.FAMILY_WAR_IS_WAR_TIME
        Msg.send(msgErr, human.fd)
        return
    end
    if not target.fwar then
        local cnt = 0
        for k, v in ipairs(family.memberList) do
            if v.fwar then
                cnt = cnt + 1
            end
        end
        if cnt >=20 then
            msgErr.msg = Lang.FAMILY_WAR_JOIN_FULL
            Msg.send(msgErr, human.fd)
            return 
        end
        target.fwar = 1
    else
        target.fwar = nil
    end
    local msg = Msg.gc.GC_FAMILY_WAR_JOIN
    msg.uuid = uuid
    msg.isFamilyWar = target.fwar and 1 or 0
    Msg.send(msg, human.fd)
end


function createFamilyWarWinner(family)
     local nSend2Ldata = {
            type = 14,
            result = family,
    }
    InnerDataManagerFW.Send2LInnerData(nil, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata, Map.get_logic_id(Map.getHomeMapID()))
end

function sendFamilyTaoyuanData(human)
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return
    end
    local member = FamilyManager.getMember(family, human._id)
    if not member then
        return
    end
    local msg = Msg.gc.GC_FAMILY_ACT_TY_QUERY
    msg.curVal = family.taoyuanValue
    msg.maxVal = FamilyDefine.FAMILY_TAOYUAN_MAX_VALUE
    if human.db.taoyuanLastFreeTime == 0 then
        msg.freeLeftTime = 0
    else
        msg.freeLeftTime = FamilyDefine.FAMILY_TAOYUAN_FREE_COOLDOWN - (os.time() - human.db.taoyuanLastFreeTime)
        if msg.freeLeftTime < 0 then
            msg.freeLeftTime = 0
        end 
    end
    
    msg.freeContribute = FamilyDefine.FAMILY_TAOYUAN_FREE_CONTRIBUTE
    msg.freeExp = FamilyDefine.FAMILY_TAOYUAN_FREE_EXP
    msg.ybContribute = FamilyDefine.FAMILY_TAOYUAN_YB_CONTRIBUTE
    msg.ybExp = FamilyDefine.FAMILY_TAOYUAN_YB_EXP
    msg.yb = FamilyDefine.FAMILY_TAOYUAN_YB
    
    if human.db.taoyuanVersion == 0 or family.taoyuanVersion == human.db.taoyuanVersion then
        msg.old = 0
        msg.icon = ItemDefine.getValue(ItemDefine.ITEM_ID_GOOD_TAO, "icon")
    else
        msg.old = 1
        msg.icon = ItemDefine.getValue(ItemDefine.ITEM_ID_BAD_TAO, "icon")
    end
    for i = 0, 4 do
      msg.status[i+1] = human.db.taoyuanReward[i] == 1 and 1 or 0
    end
    msg.status[0] = 5 
    Msg.send(msg, human.fd)
end 
--桃园结义供奉
function familyTaoyuanGive(human, family, free)
    if free then
       family.taoyuanValue = family.taoyuanValue + FamilyDefine.FAMILY_TAOYUAN_FREE_EXP
       setFamilyContribution(human, FamilyDefine.FAMILY_TAOYUAN_FREE_CONTRIBUTE)       
    else
       family.taoyuanValue = family.taoyuanValue + FamilyDefine.FAMILY_TAOYUAN_YB_EXP
       setFamilyContribution(human, FamilyDefine.FAMILY_TAOYUAN_YB_CONTRIBUTE)
    end
    if family.taoyuanValue >=FamilyDefine.FAMILY_TAOYUAN_MAX_VALUE then
       family.taoyuanValue = 0
       family.taoyuanVersion = family.taoyuanVersion + 1
       for k, v in ipairs(family.memberList) do
          local h = Human.onlineUuid[v.uuid]
          if h and h.fd then
              local ok =true
              for i = 0, 4 do
                  if h.db.taoyuanReward[i] == 1 then
                      ok = nil
                      break
                  end
              end
              if ok then
                  for i = 0, 4 do
                      h.db.taoyuanReward[i] = 1
                  end
                  h.db.taoyuanVersion = family.taoyuanVersion
              end
          end
       end    
       FamilyManager.sendFamily(Msg.gc.GC_FAMILY_ACT_TY_NOTIFY, family)   
    end
    sendContribution(human, family)
    sendFamilyTaoyuanData(human)
   
    
end
--收桃子
function familyTaoyuanGetReward(human, index)
    if index < 0 or index >4 then
        return
    end
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        return
    end
    local member = FamilyManager.getMember(family, human._id)
    if not member then
        return
    end
    if human.db.taoyuanReward[index] ~= 1 then
        return
    end
    local good 
    if family.taoyuanVersion == human.db.taoyuanVersion then
        good = true
    end    
    local nSend2Ldata = {
            type = 16,
            good = good,
            index = index,
    }
    InnerDataManagerFW.Send2LInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
end
